package com.scorpio.redis.cachelock;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * redis 方案
 */
@Aspect
@Configuration
public class LockMethodInterceptor {

    @Autowired
    public LockMethodInterceptor(RedisLock redisLock) {
        this.redisLock = redisLock;
    }

    private final RedisLock redisLock;


    @Around("execution(public * *(..)) && @annotation(com.scorpio.redis.cachelock.CacheLock)")
    public Object interceptor(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        CacheLock lock = method.getAnnotation(CacheLock.class);
        if (StringUtils.isEmpty(lock.lockKey())) {
            throw new RedisLockException("lock key can't be null...");
        }
        try {
            if (redisLock.lock(lock.lockKey(), lock.expire())) {
                try {
                    return pjp.proceed();
                } catch (Throwable throwable) {
                    throw new RedisLockException("系统异常",throwable);
                }
            } else {
                throw new RedisLockException("超时异常");
            }
        } finally {
            //如果演示的话需要注释该代码;实际应该放开
            redisLock.unlock(lock.lockKey());
        }
    }
}
